#include "head.h"
//目录栈
char* dir_stack[100]={0};
int top=0;    
int tag=0;
//初始化根目录
char tmp_path[200]={0};
void init_root()
{
    //初始化根目录
    dir_stack[0]="/";
    top++;
}
void clean_dir()
{
    for(int i=1;i<top;i++)
    {
        free(dir_stack[i]);
    }
}

void push_dir(const char*dir)
{
    //为字符串数组申请一块空间，存储需要复制的字符串dir
    //同时，返回已经开辟的空间地址
    //如果不开辟空间，则会出现段错误
    dir_stack[top]=strdup(dir);
    top++;

}
void pop_dir()
{
    if(top>1)
    {
        free(dir_stack[--top]);

    }
}

void stack_print()
{
    //从1开始打印，否则打印结果不正确
    for(int i=1;i<top;i++)
    {
        printf("/%s",dir_stack[i]);
    }
    printf("\n");
}

void stack_strcat()
{
    for(int i=1;i<top;i++)
    {
        strcat(tmp_path,"/");
        strcat(tmp_path,dir_stack[i]);
    }
}
void cat_vpath(char*vpath)
{
    //用于判断是否访问到根路径
    int flag=0;
    for(int i=1;i<top;i++)
    {
        if(i==tag)
        {
            flag=1;
            continue;
        }
        if(flag==1)
        {
            strcat(vpath,dir_stack[i]);
            flag=2;
            continue;
        }
        if(flag==2)
        {
            strcat(vpath,"/");
            strcat(vpath,dir_stack[i]);
        }
    }
}

int server_cd(int client_fd,char*cmd_argv,char* cur_path){
    //服务器端主线程分配给子线程，子线程从client——fd接受到数据cmd——argv。
    //检查用户目录文件下是否有文件夹与cmdargv匹配，


    //用client_fd进行取巧操作。
    //如果收到的fd为-1，则代表为rm操作
    top=0;  
    tag=0;
    printf("----cd start---\n");
    memset(dir_stack,0,sizeof(dir_stack));
    memset(tmp_path,0,sizeof(tmp_path));
    char vpath[200]={0};  
    char cur_tmp_path[200]={0};
    strcpy(cur_tmp_path,cur_path);
    int res=0;
    int flag=0;
    //记录server的位置
    init_root();
    char*token;
    //先将当前维护的路径push进栈内，方便后续比较
    token=strtok(cur_tmp_path,"/");
    while(token!=NULL)
    {
        push_dir(token);
        if(strcmp(token,"server")==0&&flag==0)
        {
            flag=1;
            tag=top-1;
        }
        token=strtok(NULL,"/");
    }

    token=strtok(cmd_argv,"/");

    while(token!=NULL)
    {
        if(strcmp(token,"..")==0)
        {
            pop_dir();
            if(strcmp(dir_stack[top-1],"server")==0&&top-1==tag)
            {

                printf("you can not access root file\n");
                res=-1;
                send(client_fd,&res,sizeof(int),MSG_NOSIGNAL);
                clean_dir();
                return -1;
            }
        }
        else if(strcmp(token,".")==0)
        {
        }
        else
        {
            push_dir(token);

        }
        token=strtok(NULL,"/");
    }
    //token=strtok(NULL,"/");

    stack_strcat();
    res=access(tmp_path,F_OK);
    //先判断正常cd操作
    if(client_fd!=-1)
    {      
        if(res==0)
        {
            struct stat file_stat;
            if (stat(tmp_path, &file_stat) == -1) {

                perror("stat failed");
                return -1;
            }
            if(S_ISDIR(file_stat.st_mode))
            {   
                //代表正常cd

                send(client_fd,&res,sizeof(int),MSG_NOSIGNAL);
                printf("succeed to cd\n");
                //返回成功信息后，将需要的路径发回去
                //此外，更新当前路径
                //额外需要一个切割，不能把工作路径传递回去
                cat_vpath(vpath);
                send(client_fd,vpath,sizeof(vpath),MSG_NOSIGNAL);
                strcpy(cur_path,tmp_path);
                clean_dir();
            }
            else
            {
                res=-1;
                send(client_fd,&res,sizeof(int),MSG_NOSIGNAL);
                printf("fail to cd\n");
                return -1;
            }
        }
        else
        {
            send(client_fd,&res,sizeof(int),MSG_NOSIGNAL);
            printf("fail to cd\n");
            return -1;
        }
        printf("------the op end-----\n");
        return 0;
    }
    //用于处理rm逻辑
    if(client_fd==-1)
    {

        if(res==0)
        {
            struct stat file_stat;
            if (stat(tmp_path, &file_stat) == -1) {

                perror("stat failed");
                return -1;
            }
            //判断是否是文件
            if(S_ISREG(file_stat.st_mode))
            {   
                //rm无法删除目录，显示不能删除
                printf("valid path.you can remove the file\n");
                strcpy(cur_path,tmp_path);
                clean_dir();
                //返回成功信息后，将需要的路径发回去
                //此外，更新当前路径
                //额外需要一个切割，不能把工作路径传递回去
                return 0;
            }
            else
            {
                printf("you can not remove link or directory\n");
                clean_dir();
                return -1;
            }
        }
        //如果文件路径无效
        else
        {
            printf("path is wrong.\n");
            clean_dir();
            return -1;
        }
        printf("------the op end-----\n");
        return 0;
    }
}


